# --*-- conding:utf-8 --*--
from tkinter import filedialog
import xmindparser
import os

import pandas as pd
from openpyxl import load_workbook
from openpyxl.styles import Border, Side, PatternFill, Alignment, Font
import tkinter as tk


def extract_leaf_paths_with_parents(node, path=None, result=None):
    if result is None:
        result = []
    if path is None:
        path = []

        # 将当前节点添加到路径中
    path.append({'title': node['title'], 'makers': node.get('makers', [])})

    # 检查是否为叶子节点
    if 'topics' in node and node['topics']:
        # 如果不是叶子节点，递归处理子节点
        for subnode in node['topics']:
            extract_leaf_paths_with_parents(subnode, path.copy(), result)
    else:
        # 如果是叶子节点，反转路径（因为我们是从根开始构建的，但要求从叶子开始）
        # 只保留每个节点的标题和优先级（如果有的话）
        processed_path = [{'title': item['title'], 'makers': item['makers']} for item in path]
        # 将处理后的路径添加到结果列表中
        result.append(processed_path)

        # 注意：这里不返回path或result，因为我们在递归中直接修改了result

    return result


class xmindTOexcel:
    def __init__(self, path, filename):
        """调用类时，读取xmind文件，并生成excel表格"""
        try:
            self.xm = xmindparser.xmind_to_dict(path)[0]['topic']
            self.filename = filename
            # 打印xmind文件的结构体
            # print(self.xm)
        except Exception as e:
            print(f"打开xmind文件失败:{e}")

    def main(self):
        data = []
        line_one = ['''此导入模板根据相应用例创建页面所生成, 需要注意以下事项: 
1. 表头字段标题不能更改, 更不能增加或删除; 
2. 红色标题所在列为必填字段; 
3. 附带下拉列表的单元格需正确选择下拉列表中的选项; 
4. 复选框字段可以填写多个, 但必须以英文逗号分隔开; 
5. 人员输入框必须输入项目中可以选择的人员姓名, 多个人员使用英文逗号分隔开; 
6. 分组为当前人工用例库中已经存在的分组，格式为：一级节点/二级节点/三级节点……; 
7. 日期字段填写格式: yyyy-MM-dd; 
8. 需求字段填写需求编号，一个用例仅支持关联一个需求;
9. 一次最多可导入10000条用例''', '', '', '', '', '', '']
        # data.append(line_one)
        line_two = ['用例名称', '分组', '等级', '需求', '前置条件', '步骤描述', '预期结果']
        data.extend([line_one, line_two])
        result = extract_leaf_paths_with_parents(self.xm)

        # 统计各等级用例数量
        high_count = 0
        medium_count = 0

        found_high = False
        for path in result:
            m = ['', '', '']
            # 打印每个路径，以逗号分隔标题，并显示优先级（如果有的话）
            mingcheng = ' -> '.join(f"{item['title']}" for item in path[1:-2])
            buzou = path[-2]['title']
            yuqi = path[-1]['title']
            m.insert(0, mingcheng)
            m.extend([buzou, yuqi])
            dengji = '中' # 默认等级为中

            # 检查是否有高优先级标记
            found_high = False
            for item in path:
                if item['makers'] == ['priority-1'] or item['makers'] == ['priority-1', 'flag-red'] or item['makers'] == ['flag-red', 'priority-1']:
                    dengji = '高'
                    high_count += 1
                    found_high = True
                    break

            if not found_high:
                medium_count += 1

            m.insert(2, dengji)
            data.append(m)
        print("冒烟用例",high_count)
        print("中等级用例",medium_count)
        print("总用例数:", high_count + medium_count, "冒烟比例：", int(high_count / (high_count + medium_count) * 100),"%")

        """生成excel文件的方法"""
        df = pd.DataFrame(data[1:], columns=data[0])

        # 将DataFrame写入Excel文件
        file_path = os.path.join(os.getcwd(), r'files\download\\', self.filename)
        file_path = ''.join([file_path, '.xlsx'])
        df.to_excel(file_path, index=False)
        print("文件路径：",file_path)

        # 加载Excel文件以修改样式
        wb = load_workbook(file_path)
        ws = wb.active

        # 合并第一行的单元格
        ws.merge_cells('A1:G1')

        # 设置列宽[80, 20, 10, 10, 10, 80, 80]
        ws.column_dimensions['A'].width = 80
        ws.column_dimensions['B'].width = 20
        ws.column_dimensions['C'].width = 10
        ws.column_dimensions['D'].width = 10
        ws.column_dimensions['E'].width = 10
        ws.column_dimensions['F'].width = 80
        ws.column_dimensions['G'].width = 80

        # 设置行高
        ws.row_dimensions[1].height = 140
        for i in range(2, ws.max_row + 1):
            ws.row_dimensions[i].height = 30

        # 设置单元格颜色
        fill = PatternFill(start_color="98FB98", end_color="98FB98", fill_type="solid")
        # 注意：由于第一行已合并，我们只需要为合并后的单元格设置颜色
        # 遍历该行的所有单元格，并应用填充样式
        for cell in ws[2]:
            cell.fill = fill

        # 设置边框样式
        thin_border = Border(left=Side(style='thin'),
                             right=Side(style='thin'),
                             top=Side(style='thin'),
                             bottom=Side(style='thin'))
        # 应用边框样式到所有单元格（包括合并后的单元格）
        for row in ws.iter_rows():
            for cell in row:
                cell.border = thin_border
            # 注意：合并后的单元格边框可能需要特别处理，以确保边框看起来正确

        # 创建一个Alignment对象，设置水平和垂直居中
        alignment = Alignment(horizontal='left', vertical='center')

        # 应用全局居中样式
        for row in ws.iter_rows():
            for cell in row:
                cell.alignment = alignment

        # 假设第一行是标题行，我们想要取消其加粗效果
        if ws.max_row >= 1:  # 确保工作表中有至少一行数据
            for col in ws[1]:  # 遍历第一行的所有单元格
                # 创建一个非加粗的字体对象
                font = Font(bold=False)
                # 应用非加粗的字体到当前单元格
                col.font = font

                # 保存修改后的Excel文件
        wb.save(file_path)


if __name__ == "__main__":
    root = tk.Tk()
    root.withdraw()  # 隐藏主窗口
    # 弹出文件选择框
    path = filedialog.askopenfilename(
        title="选择xmind文件",
        filetypes=(("Text files", "*.xmind"), ("All files", "*.*"))
    )
    parts = path.split('\\')
    filename_with_ext = parts[-1]
    filename_without_ext = filename_with_ext.rsplit('.', 1)[0]
    xx = xmindTOexcel(path, filename_without_ext)
    xx.main()
